﻿using System;
using System.Collections.Generic;
using Gasco.DataAccess;
using System.Linq;
using System.Data.Linq;
using System.Reflection;

namespace Gasco.Business.Services
{
    public class ContactService : IContactService
    {

        #region IContactService Members


        public contact GetContactById(int id)
        {
            contact contact = null;

            using (var db = DatabaseHelper.GetData())
            {
                DataLoadOptions lo = new DataLoadOptions();
                lo.LoadWith<contact>(c => c.personal_contact);
                lo.LoadWith<contact>(o => o.company_contact);
                db.LoadOptions = lo;
                db.DeferredLoadingEnabled = false;
                contact = (from p in db.contacts
                           where p.id == id
                           select p).First();
            }

            contact.SetAsChangeTrackingRoot(true);
            return contact;
        }

        public int GetContactIdByName(string name)
        {
            if (String.IsNullOrEmpty(name))
                return 0;

            contact contact = null;

            using (var db = DatabaseHelper.GetData())
            {
                contact = (from p in db.contacts
                           where p.name == name
                           select p).FirstOrDefault();
            }

            if (contact == null)
            {
                throw new ContactNameNotFoundException(name);
            }

            return contact.id;
        }

        public contact CreateContact(contact c)
        {
            return DatabaseHelper.Insert<contact>(c);
        }

        public void UpdateContact(contact c)
        {
            DatabaseHelper.Update<contact>(c);
        }

        public void DeleteContact(int id)
        {
            contact c = GetContactById(id);
            DatabaseHelper.Delete<contact>(c);    
        }
 
        public int CountContacts()
        {
            using (var db = DatabaseHelper.GetData())
            {
                return db.contacts.Count();
            }
        }

        public List<contact> AutoCompleteByName(string name)
        {
            var db = DatabaseHelper.GetData();
            var result = from c in db.contacts
                         where c.name.Contains(name)
                         select c;

            return result.Take(10).ToList<contact>();
        }

        public List<contact> SearchContacts(string keyword, int pageSize, int pageNumber, string sortBy, string sortDirection)
        {
            var db = DatabaseHelper.GetData();
            IQueryable<contact> result = null;

            if (String.IsNullOrEmpty(keyword))
            {

                result = from c in db.contacts
                             select c;
            }
            else
            {
                result = from c in db.contacts
                             where ((c.activity_field.Contains(keyword)) || (c.account_info.Contains(keyword)) ||
                                   (c.address.Contains(keyword)) || (c.email.Contains(keyword)) ||
                                   (c.fax.Contains(keyword)) || (c.name.Contains(keyword)) || 
                                   (c.company_contact.ceo_name.Contains(keyword)) ||
                                   (c.company_contact.ceo_tel.Contains(keyword)) || (c.company_contact.ceo_mobile.Contains(keyword)) ||
                                   (c.company_contact.corr_name.Contains(keyword)) || (c.company_contact.corr_tel.Contains(keyword)) ||
                                   (c.company_contact.corr_mobile.Contains(keyword)) || (c.company_contact.register_code.Contains(keyword)) ||
                                   (c.personal_contact.father_name.Contains(keyword)) || (c.personal_contact.identity_id.Contains(keyword)) ||
                                   (c.personal_contact.national_code.Contains(keyword)) || (c.personal_contact.mobile.Contains(keyword)) ||
                                   (c.personal_contact.home_tel.Contains(keyword)) || (c.personal_contact.work_tel.Contains(keyword)))
                             select c;
            }

            if (sortDirection.ToLower() == "descending")
                sortBy = String.Format("{0} DESC", sortBy);

            return result.Skip((pageNumber - 1) * pageSize).Take(pageSize).SortBy<contact>(sortBy).ToList<contact>();
        }

        public int CountSearchContacts(string keyword)
        {
            var db = DatabaseHelper.GetData();
            IQueryable<contact> result = null;

            if (String.IsNullOrEmpty(keyword))
            {

                result = from c in db.contacts
                         select c;
            }
            else
            {
                result = from c in db.contacts
                         where ((c.activity_field.Contains(keyword)) || (c.account_info.Contains(keyword)) ||
                               (c.address.Contains(keyword)) || (c.email.Contains(keyword)) ||
                               (c.fax.Contains(keyword)) ||(c.name.Contains(keyword)) || (c.company_contact.ceo_name.Contains(keyword)) ||
                               (c.company_contact.ceo_tel.Contains(keyword)) || (c.company_contact.ceo_mobile.Contains(keyword)) ||
                               (c.company_contact.corr_name.Contains(keyword)) || (c.company_contact.corr_tel.Contains(keyword)) ||
                               (c.company_contact.corr_mobile.Contains(keyword)) || (c.company_contact.register_code.Contains(keyword)) ||
                               (c.personal_contact.father_name.Contains(keyword)) || (c.personal_contact.identity_id.Contains(keyword)) ||
                               (c.personal_contact.national_code.Contains(keyword)) || (c.personal_contact.mobile.Contains(keyword)) ||
                               (c.personal_contact.home_tel.Contains(keyword)) || (c.personal_contact.work_tel.Contains(keyword)))
                         select c;
            }

            return result.Count();
        }

        #endregion
    }
}
